What is retry-axios?
retry-axios is a lightweight library that adds automatic retry functionality to axios requests. It allows you to specify retry conditions, delay strategies, and maximum retry attempts, making it easier to handle transient errors in HTTP requests.
What are retry-axios's main functionalities?
Automatic Retries
This feature allows you to automatically retry failed HTTP requests based on specified conditions. The code sample demonstrates how to configure retry-axios to retry a GET request up to 3 times with a delay of 100ms between attempts.
const axios = require('axios');
const rax = require('retry-axios');
const instance = axios.create();
instance.defaults.raxConfig = {
instance,
retry: 3,
noResponseRetries: 2,
retryDelay: 100,
httpMethodsToRetry: ['GET', 'HEAD', 'OPTIONS', 'DELETE', 'PUT'],
statusCodesToRetry: [[100, 199], [429, 429], [500, 599]],
onRetryAttempt: err => {
const cfg = rax.getConfig(err);
console.log(`Retry attempt #${cfg.currentRetryAttempt}`);
}
};
rax.attach(instance);
instance.get('https://example.com')
.then(response => console.log(response.data))
.catch(error => console.error(error));
Custom Retry Logic
This feature allows you to define custom retry logic. The code sample shows how to retry a request only if the response status is 503 (Service Unavailable) and the retry attempt is less than 3.
const axios = require('axios');
const rax = require('retry-axios');
const instance = axios.create();
instance.defaults.raxConfig = {
instance,
retry: 3,
retryDelay: 100,
shouldRetry: (err) => {
const cfg = rax.getConfig(err);
return err.response.status === 503 && cfg.currentRetryAttempt < 3;
}
};
rax.attach(instance);
instance.get('https://example.com')
.then(response => console.log(response.data))
.catch(error => console.error(error));
Exponential Backoff
This feature allows you to use exponential backoff for retry delays. The code sample demonstrates how to configure retry-axios to use exponential backoff with a base delay of 100ms.
const axios = require('axios');
const rax = require('retry-axios');
const instance = axios.create();
instance.defaults.raxConfig = {
instance,
retry: 3,
retryDelay: 100,
backoffType: 'exponential',
onRetryAttempt: err => {
const cfg = rax.getConfig(err);
console.log(`Retry attempt #${cfg.currentRetryAttempt}`);
}
};
rax.attach(instance);
instance.get('https://example.com')
.then(response => console.log(response.data))
.catch(error => console.error(error));
Other packages similar to retry-axios
axios-retry
axios-retry is another library that adds retry functionality to axios. It provides similar features such as automatic retries, custom retry logic, and exponential backoff. However, retry-axios offers more granular control over retry conditions and additional configuration options.
superagent-retry
superagent-retry is a plugin for the SuperAgent HTTP client that adds retry functionality. While it provides basic retry capabilities, it lacks the advanced configuration options and integration with axios that retry-axios offers.
fetch-retry
fetch-retry is a library that adds retry functionality to the Fetch API. It provides similar features such as automatic retries and exponential backoff. However, it is designed for use with the Fetch API rather than axios, making it less suitable for projects that rely on axios.
retry-axios
Use Axios interceptors to automatically retry failed requests. Super flexible. Built in exponential backoff.
Installation
npm install retry-axios
Usage
To use this library, import it alongside of axios
:
const rax = require('retry-axios');
const axios = require('axios');
Or, if you're using TypeScript / es modules:
import * as rax from 'retry-axios';
import axios from 'axios';
You can attach to the global axios
object, and retry 3 times by default:
const interceptorId = rax.attach();
const res = await axios('https://test.local');
Or you can create your own axios instance to make scoped requests:
const myAxiosInstance = axios.create();
myAxiosInstance.defaults.raxConfig = {
instance: myAxiosInstance
};
const interceptorId = rax.attach(myAxiosInstance);
const res = await myAxiosInstance.get('https://test.local');
You have a lot of options...
const interceptorId = rax.attach();
const res = await axios({
url: 'https://test.local',
raxConfig: {
retry: 3,
noResponseRetries: 2,
retryDelay: 100,
httpMethodsToRetry: ['GET', 'HEAD', 'OPTIONS', 'DELETE', 'PUT'],
statusCodesToRetry: [[100, 199], [429, 429], [500, 599]],
instance: ax,
backoffType: 'exponential',
onRetryAttempt: err => {
const cfg = rax.getConfig(err);
console.log(`Retry attempt #${cfg.currentRetryAttempt}`);
}
}
});
If the logic in onRetryAttempt requires to be asynchronous, you can return a promise, then retry will be executed only after the promise is resolved:
const res = await axios({
url: 'https://test.local',
raxConfig: {
onRetryAttempt: err => {
return new Promise((resolve, reject) => {
refreshToken(err, function(token, error) {
if (!error) {
window.localStorage.setItem('token', token);
resolve();
} else {
reject();
}
});
});
}
}
});
Or if you want, you can just decide if it should retry or not:
const res = await axios({
url: 'https://test.local',
raxConfig: {
shouldRetry: err => {
const cfg = rax.getConfig(err);
return true;
}
}
});
If you want to add custom retry logic without duplicating too much of the built-in logic, rax.shouldRetryRequest
will tell you if a request would normally be retried:
const res = await axios({
url: 'https://test.local',
raxConfig: {
shouldRetry: err => {
const cfg = rax.getConfig(err);
if (cfg.currentRetryAttempt >= cfg.retry) return false
if (err.response.statusText.includes('Try again')) return true
return rax.shouldRetryRequest(err)
}
}
});
How it works
This library attaches an interceptor
to an axios instance you pass to the API. This way you get to choose which version of axios
you want to run, and you can compose many interceptors on the same request pipeline.
License
Apache-2.0